package com.bsoft.hospitalchs.ui.login;

import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.os.Looper;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Log;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;

import com.bsoft.hospitalchs.api.ApiService;
import com.bsoft.hospitalchs.api.SimpleMyCallBack;
import com.bsoft.hospitalchs.api.progress.DownloadProgressHandler;
import com.bsoft.hospitalchs.api.progress.ProgressHelper;
import com.bsoft.hospitalchs.base.BaseCommonPresenter;
import com.bsoft.hospitalchs.common.MyApplication;
import com.bsoft.hospitalchs.model.CharacterBean;
import com.bsoft.hospitalchs.model.CharacterResBean;
import com.bsoft.hospitalchs.model.HttpExceptionBean;
import com.bsoft.hospitalchs.model.RoleBean;
import com.bsoft.hospitalchs.ui.login.update.UpdataInfo;
import com.bsoft.hospitalchs.ui.login.update.UpdataInfoParser;
import com.bsoft.hospitalchs.utils.SpUtils;
import com.bsoft.hospitalchs.utils.ToastUtils;
import com.bsoft.hospitalchs.utils.Tools;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.socks.library.KLog;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observable;
import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Func1;
import rx.schedulers.Schedulers;

import static com.bsoft.hospitalchs.utils.FilesUtils.clearInfoForFile;
import static com.bsoft.hospitalchs.utils.FilesUtils.readFile;
import static com.bsoft.hospitalchs.utils.FilesUtils.writeByBufferedReader;

/**
 * Created by 泅渡者
 * Created on 2017/5/10.
 */

public class LoginPresenter extends BaseCommonPresenter<LoginContract.View> implements LoginContract.Presenter {

    private static final String TAG = "LoginPresenter";
    private boolean isReload = true;//默认网络获取
    private static String cacheName = "Role.txt";//默认缓存文件名称
    private UpdataInfo updataInfo;


    public LoginPresenter(LoginContract.View view, Context context) {
        super(view, context);
    }

    @Override
    public void toSetinfo(EditText arg1, EditText arg2, TextView arg3, TextView arg4, boolean isRemember) {
        arg1.setText((String) SpUtils.get(context, "UserName", ""));
        arg2.setText((String) SpUtils.get(context, "PassWord", ""));
        arg3.setText((String) SpUtils.get(context, "Character", ""));
        arg4.setText((String) SpUtils.get(context, "Department", ""));
    }

    @Override
    public void toSetRememberStatue(CheckBox cb) {
        cb.setOnCheckedChangeListener(null);
        if (MyApplication.isRemember()) {
            cb.setChecked(true);
        } else {
            cb.setChecked(false);
        }
        cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    MyApplication.setIsRemember(true);
                } else {
                    MyApplication.setIsRemember(false);
                }
            }
        });
    }

    /**
     * 获取数据 true 网络
     * false 本地
     *
     * @param isdel
     */
    @Override
    public void toGetCharacter(boolean isdel) {
        CharacterBean characterBean = new CharacterBean();
        characterBean.setUid(SpUtils.get(context, "UserName", "").toString());
        characterBean.setPwd(SpUtils.get(context, "PassWord", "").toString());
        characterBean.setMethod("execute");
        characterBean.setUrl("logon/myRoles");
        if (isdel) { //重新加载
            clearInfoForFile(context, cacheName);
            isReload = true;
        } else { //读取本地
            isReload = false;
        }

        if (isReload) {
            mCompositeSubscription.add(apiImple.doGetCharacter(characterBean)
                    .subscribe(newMySubscriber(new SimpleMyCallBack<CharacterResBean>() {
                        @Override
                        public void onError(HttpExceptionBean mHttpExceptionBean) {
                            super.onError(mHttpExceptionBean);
                            ToastUtils.showShort(mHttpExceptionBean.toString());
                        }

                        @Override
                        public void onNext(CharacterResBean bean) {
                            if (bean.getCode() == 200 && !TextUtils.isEmpty(bean.getBody().toString())) {
                                Gson gson = new Gson();
                                String str = gson.toJson(bean);
                                KLog.json(str);
                                toWriteFile(str);
                            } else if (bean.getCode() == 404) {
                                ToastUtils.showShort("账号不存在！");
                            } else if (bean.getCode() == 501) {
                                ToastUtils.showShort("密码不正确！");
                            } else {
                                ToastUtils.showShort("服务器响应异常！");
                            }

                        }
                    })));
        } else {
            toReadFile(cacheName);
        }

    }

    private void toWriteFile(final String str) {
        Observable observable = Observable.just(str);
        observable.map(new Func1<String, Boolean>() {
            @Override
            public Boolean call(String content) {
                return writeByBufferedReader(context, cacheName, str);
            }
        }).subscribeOn(Schedulers.io())//当前线程(子线程)发布
                .observeOn(AndroidSchedulers.mainThread())//UI线程执行(更新图片)
                .subscribe(new Subscriber<Boolean>() {
                    @Override
                    public void onCompleted() {
                        Log.i(TAG, "写入完成");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i(TAG, "写入失败" + e.getMessage());
                    }

                    @Override
                    public void onNext(Boolean flag) {
                        Log.i(TAG, "写入成功");
                        if (flag) {
                            toReadFile(cacheName);
                        }
                    }
                });


    }

    private void toReadFile(String filename) {

        Observable observable = Observable.just(filename);
        observable.map(new Func1<String, String>() {
            @Override
            public String call(String filename) {
                return readFile(context, filename);
            }
        }).subscribeOn(Schedulers.io())//当前线程(子线程)发布
                .observeOn(AndroidSchedulers.mainThread())//UI线程执行(更新图片)
                .subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {
                        Log.i(TAG, "读取完成");
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.i(TAG, "读取失败" + e.getMessage());
                        view.reLoad();
                    }

                    @Override
                    public void onNext(String str) {
                        Log.i(TAG, "读取成功" + str);
                        try {
                            JSONObject json = new JSONObject(str);
                            int code = json.optInt("code");
                            switch (code) {
                                case 404:
                                    ToastUtils.showShort("账号不存在！");
                                    return;
                                case 501:
                                    ToastUtils.showShort("密码不正确！");
                                    return;
                            }
                            JSONArray tioken = json.optJSONObject("body").optJSONArray("tokens");
                            List<RoleBean> roleList = new ArrayList<RoleBean>();
                            for (int i = 0; i < tioken.length(); i++) {
                                JSONObject objecy = tioken.optJSONObject(i);
                                RoleBean roleBean = new RoleBean();
                                roleBean.setRole_id(objecy.optInt("id"));
                                roleBean.setManageUni_id(objecy.optJSONObject("manageUnit").optInt("id"));
                                roleBean.setRole_name(objecy.optJSONObject("role").optString("name") + "(" + objecy.optJSONObject("manageUnit").optString("name") + ")");
                                roleBean.setManageUni_name(objecy.optJSONObject("manageUnit").optString("name"));
                                roleBean.setCreateUnit_id(objecy.optString("manageUnitId"));
                                roleList.add(roleBean);
                            }
                            view.showPopupWindow(roleList);

                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });
    }

    @Override
    public void toLogin(String arg1, String arg2, String arg3, String arg4, String arg5) {
        mCompositeSubscription.add(apiImple.doLogin(arg1, arg2, arg3, arg4, arg5)
                .subscribe(newMySubscriber(new SimpleMyCallBack<JsonObject>() {
                    @Override
                    public void onError(HttpExceptionBean mHttpExceptionBean) {
                        super.onError(mHttpExceptionBean);
                        ToastUtils.showShort("网络异常.....");
                    }

                    @Override
                    public void onNext(JsonObject str) {
                        view.toJumpActivity();
                    }
                })));
    }

    /**
     * 版本更新入口
     */
    @Override
    public void toUpdate() {
        if (!Tools.isNetworkAvailable(context))
            return;
        String path = " http://219.234.5.196/dl/version_pad.xml";
        GetServerVersion downloadTask = new GetServerVersion(context);
        downloadTask.execute(path);
    }

    class GetServerVersion extends AsyncTask<String, Integer, UpdataInfo> {

        private Context context;

        public GetServerVersion(Context context) {
            this.context = context;
        }

        @Override
        protected UpdataInfo doInBackground(String... params) {

            try {
                URL url = new URL(params[0]);

                HttpURLConnection conn = (HttpURLConnection) url
                        .openConnection();
                conn.setRequestProperty("Accept-Encoding", "identity");
                conn.connect();
                InputStream is = conn.getInputStream();
                updataInfo = UpdataInfoParser.getUpdataInfo(is);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return updataInfo;
        }

        @Override
        protected void onPostExecute(final UpdataInfo updataInfo) {
            super.onPostExecute(updataInfo);
            if (updataInfo.getVersion().equals(getLocalVersion() + "")) {
                Log.d(TAG, "版本无变化");
            } else {
                new AlertDialog.Builder(context)
                        .setTitle("版本升级")
                        .setMessage("当前有新版本，是否更新？")
                        .setPositiveButton("是", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                if (null == updataInfo)
                                    return;
                                retrofitDownload(updataInfo.getUrl());
                            }
                        })
                        .setNegativeButton("否", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                            }
                        })
                        .show();

            }
        }
    }

    /**
     * 获取当前APP版本号
     */
    private int getLocalVersion() {

        return Tools.getVersion(context);
    }

    private void retrofitDownload(String url) {
        //监听下载进度
        final ProgressDialog dialog = new ProgressDialog(context);
        dialog.setProgressNumberFormat("%1d MB/%2d MB");
        dialog.setTitle("下载");
        dialog.setMessage("正在下载，请稍后...");
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setCancelable(false);
        dialog.show();

        Retrofit.Builder retrofitBuilder = new Retrofit.Builder()
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(MyApplication.getInstance().getBase_url());
        OkHttpClient.Builder builder = ProgressHelper.addProgress(null);
        ApiService retrofit = retrofitBuilder
                .client(builder.build())
                .build().create(ApiService.class);

        ProgressHelper.setProgressHandler(new DownloadProgressHandler() {
            @Override
            protected void onProgress(long bytesRead, long contentLength, boolean done) {
                Log.e("是否在主线程中运行", String.valueOf(Looper.getMainLooper() == Looper.myLooper()));
                Log.e("onProgress", String.format("%d%% done\n", (100 * bytesRead) / contentLength));
                Log.e("done", "--->" + String.valueOf(done));
                Log.e("contentLength", "--->" + contentLength);
                dialog.setMax((int) (contentLength / 1024) / 1024);
                dialog.setProgress((int) (bytesRead / 1024) / 1024);
                if (done) {
                    dialog.dismiss();
                    update();
                }
            }
        });

        Call<ResponseBody> call = retrofit.retrofitDownload(url);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                try {
                    InputStream is = response.body().byteStream();
                    File file = new File(Environment.getExternalStorageDirectory(), "晞景儿童.apk");
                    FileOutputStream fos = new FileOutputStream(file);
                    BufferedInputStream bis = new BufferedInputStream(is);
                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = bis.read(buffer)) != -1) {
                        fos.write(buffer, 0, len);
                        fos.flush();
                    }
                    fos.close();
                    bis.close();
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {

            }
        });

    }

    private void update() {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(context, "com.bsoft.hospitalchs.fileprovider",
                    new File(Environment.getExternalStorageDirectory(), "晞景儿童.apk"));
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(new File(Environment
                    .getExternalStorageDirectory(), "晞景儿童.apk")), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        if (context.getPackageManager().queryIntentActivities(intent, 0).size() > 0) {
            context.startActivity(intent);
            android.os.Process.killProcess(android.os.Process.myPid());
        }

    }
}
